<?php

namespace app\fire\model;

use app\fire\validate\Validate;
use think\facade\Request;
use think\Model;

class Base extends Model
{
    protected $tableField = [

    ];
    //对应字段的验证关系
    protected $validate = [

    ];

    protected $validateMessage = [

    ];

    protected $operation = [

    ];

    public function getPageData($arr = [])
    {
        $get = Request::get();
        $page = [];
        if (!isset($arr['field'])) $arr['field'] = ['*'];
        if (!isset($arr['order'])) $arr['order'] = $this->pk . ' DESC';
        if (!isset($arr['page_number'])) {
            $arr['page_number'] = intval($get['pageNumber']) ? intval($get['pageNumber']) : 1;
        }
        if (!isset($arr['page_size'])) {
            $arr['page_size'] = $get['pageSize'] ? $get['pageSize'] : 10;
        }
        if (!$arr['where']) $arr['where'] = [];
        $page['total'] = $this->where($arr['where'])->count();
        $limit = $get['limit'] && is_numeric($get['limit']) && $get['limit'] >= 1 ? $get['limit'] : implode(',', [($arr['page_number'] - 1) * $arr['page_size'], $arr['page_size']]);
        $page['data'] = $this->where($arr['where'])->order($arr['order'])->field($arr['field'])->limit($limit)->select()->toArray();
        $page['pageSize'] = intval($arr['page_size']);
        $page['pageNumber'] = min($arr['page_number'], ceil($page['total'] / $page['page_size']));
        return $page;
    }

    public function groupAdd($groupName, $data = [])
    {

        //获取当前这个类的所有字段信息
        $groupData = $this->operation[$groupName];
        if (empty($groupData) || empty($groupData['field'])) {
            $this->error = '操作错误!';
            return false;
        }
        if (empty($data)) $data = Request::post();
        $saveData = $this->groupValidate($groupName, $data);
        if (!$saveData) return false;
//        P($saveData);
        $add = static::create($saveData);
        return $add->toArray();
    }

    public function groupSave($id, $groupName, $data = [])
    {
        $modelData = static::get($id);
//        P($modelData->toArray());
        if (empty($modelData)) {
            $this->error = '没有此条数据!';
            return false;
        }
        //获取当前这个类的所有字段信息
        $groupData = $this->operation[$groupName];
        if (empty($groupData) || empty($groupData['field'])) {
            $this->error = '操作错误!';
            return false;
        }
        if (empty($data)) $data = Request::put();
        $saveData = $this->groupValidate($groupName, $data);
//        P($saveData);
        if (!$saveData) return false;
//        P($saveData);
//        $pk=$this->getPk();
//        $a=$this->save($saveData,[$pk=>$id]);
//        P($a);
        foreach ($saveData as $k => $v) {
            $modelData[$k] = $v;
        }

//        $modelData['type']=['a1','a4'];
//        P($modelData);
        $modelData->save();
        return $modelData->toArray();
    }

    public function createWhere($group)
    {
        $search = Request::get('search', []);
        $search = json_decode($search, true);
        $where = [];
        $group = $this->operation[$group];
        $group = array_intersect_key($this->tableField, array_flip($group['field']));
        foreach ($group as $k => $v) {
            if (!isset($search[$k]) || $search[$k] === '') continue;
            switch (strtolower($v['type'])) {
                case 'string':
                    !is_array($search[$k]) ? $where[] = [$k, 'like', '%' . $search[$k] . '%'] : true;
                    break;
                case 'date_str':
                    if (strtotime($search[$k][0]) && strtotime($search[$k][1])) {
                        $where[] = [$k, 'egt', $search[$k][0]];
                        $where[] = [$k, 'elt', $search[$k][1]];
                    }
                    break;
                case 'verify':
                    if (is_array($search[$k])) {
                        $where[] = [$k, 'in', $search[$k]];
                    }
                    break;
                case 'date_int':
                    $startTime = strtotime($search[$k][0]);
                    $endTime = strtotime($search[$k][1]);
                    if ($startTime && $endTime) {
                        $where[] = [$k, 'egt', find_time_start_end($startTime, 'day', 'start')];
                        $where[] = [$k, 'elt', find_time_start_end($endTime, 'day', 'end')];
                    }
                    break;
                case 'time_int':
                    $startTime = date('Y-m-d H:i:s', $search[$k][0]);
                    $endTime = date('Y-m-d H:i:s', $search[$k][1]);
                    if ($startTime && $endTime) {
                        $where[] = [$k, 'egt', $search[$k][0]];
                        $where[] = [$k, 'elt', $search[$k][1]];
                    }
                    break;
                case 'timestamp':
                    $search[$k] = array_map(function ($v) {
                        return floor($v / 1000);
                    }, $search[$k]);
                    $startTime = date('Y-m-d H:i:s', $search[$k][0]);
                    $endTime = date('Y-m-d H:i:s', $search[$k][1]);
                    if ($startTime && $endTime) {
                        $where[] = [$k, 'egt', $search[$k][0]];
                        $where[] = [$k, 'elt', $search[$k][1]];
                    }
                    break;
                case 'select':
                    if (!in_array($search[$k], $v['options'])) continue;
                    $where[] = [$k, '=', $search[$k]];
                    break;
                default:
                    !is_array($search[$k]) ? $where[] = [$k, '=', $search[$k]] : true;
            }
        }
        return $where;
    }

    public function createOrder($group)
    {
        $sortArr = Request::get('sort', []);
        $sortArr = json_decode($sortArr, true);
        $allowField = $this->operation[$group]['order'];
        $order = $allowField['default'];
        if (!is_array($sortArr)) return $order;
        if (!in_array($sortArr['prop'], $allowField['field'], true)) return $order;
        switch ($sortArr['order']) {
            case 'descending':
                return $sortArr['prop'] . ' DESC';
                break;
            case 'ascending':
                return $sortArr['prop'] . ' ASC';
                break;
            default:
                return $order;
        }
    }

    public function groupValidate($groupName, $data)
    {
        //获取当前这个组的字段信息
        $groupData = $this->operation[$groupName];
        if ($groupData['field']==='*'){
            $rule=$this->validate;
        }else{
            $rule = array_intersect_key($this->validate, array_flip($groupData['field']));
        }
        if (!$rule) {
            if ($groupData['field'] === '*') {
                return $data;
            } else {
                return array_intersect_key($data, array_flip($groupData['field']));
            }
        }
        if (Request::method() === 'PUT') {
            //如果是更新操作，那么$rule只会验证当前$data中的数据
            $rule = array_intersect_key($rule, $data);
        }
        $validate = new Validate();
        $validate->rule($rule);
        $validate->message($this->validateMessage);
        if (!$validate->check($data)) {
            $this->error = $validate->getError();
            return false;
        }
        //返回允许更新的字段信息
        if ($groupData['field'] === '*') {
            return $data;
        }
        return array_intersect_key($data, array_flip($groupData['field']));
    }

    public function getGroupField($group, $data = [])
    {
        $field = $this->operation[$group]['field'];
        if (!$data) {
            return $field;
        }
        return array_intersect_key($data, array_flip($field));
    }

    protected function stringToArray($value)
    {
        $value = json_decode($value, true);
        $value = array_filter($value);
        return $value ?? [];
    }

    protected function arrayToString($value)
    {
        $value = array_filter($value);
        $value = json_encode($value);
        return $value ?? '';
    }
}
